package org.jeecg.common.util.enums;

import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.Objects;
import java.util.function.Function;

import static org.apache.commons.lang3.StringUtils.contains;

/**
 * enum工具类
 *
 * @author zjarlin
 * @date 2022/12/16
 */
public final class EnumUtils {

    /**
     * 是存在
     * 判断枚举值是否存在于指定枚举数组中
     *
     * @param value     枚举值
     * @param enumClazz enum clazz
     * @param getFun    得到乐趣
     * @return 是否存在
     */
    public static <T, E extends Enum<E>> boolean isExist(Class<E> enumClazz,
                                                         Function<E, ?> getFun,
                                                         T value) {
        if (value == null) {
            return false;
        }
        E[] enumConstants = enumClazz.getEnumConstants();
        return Arrays.stream(enumConstants).map(getFun).anyMatch(e -> e.equals(value));

    }

    /**
     * 根据枚举值获取其对应的名字
     *
     * @param value 枚举值
     * @return 枚举名称
     */
    public static <L, V, E extends Enum<E>> L getLabelByValue(Class<E> enumClazz,
                                                              Function<E, L> getLabelFun,
                                                              Function<E, L> getValueFun,
                                                              V value) {
        if (value == null) {
            return null;
        }
        E[] enumConstants = enumClazz.getEnumConstants();
        return Arrays.stream(enumConstants).filter(e -> Objects.equals(getValueFun.apply(e), value)).map(e -> getLabelFun.apply(e))
                .findAny().orElse(null);
    }

    /**
     * 根据枚举名称获取对应的枚举值
     *
     * @param enums 枚举列表
     * @param name  枚举名
     * @return 枚举值
     */
    public static <T> T getValueByName(NameValueEnum<T>[] enums, String name) {
        if (StringUtils.isEmpty(name)) {
            return null;
        }
        for (NameValueEnum<T> e : enums) {
            if (name.equals(e.getName())) {
                return e.getValue();
            }
        }
        return null;
    }

    /**
     * 根据枚举值获取对应的枚举对象
     *
     * @param enums 枚举列表
     * @return 枚举对象
     */
    @SuppressWarnings("unchecked")
    public static <E extends Enum<? extends ValueEnum<V>>, V> E getEnumByValue(E[] enums, V value) {
        for (E e : enums) {
            if (((ValueEnum<V>) e).getValue().equals(value)) {
                return e;
            }
        }
        return null;
    }

    /**
     * 根据枚举值获取对应的枚举对象
     *
     * @param enumClass 枚举class
     * @return 枚举对象
     */
    public static <E extends Enum<? extends ValueEnum<V>>, V> E getEnumByValue(Class<E> enumClass, V value) {
        return getEnumByValue(enumClass.getEnumConstants(), value);
    }
}
